package com.woniu.goods.config;

import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;
import com.woniu.goods.realms.ShiroRealm;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.cache.ehcache.EhCacheManager;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.LinkedHashMap;
import java.util.Map;

/**
 * 功能描述:<br>
 * 〈〉
 *
 * @author wugd
 * @create 2021/1/29
 * @since 1.0.0
 */
@Configuration
//shiro的配置文件 加密 权限控制
public class ShiroConfig {
    //加密方式
    @Bean
    public HashedCredentialsMatcher hashedCredentialsMatcher(){
        HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
        hashedCredentialsMatcher.setHashAlgorithmName("MD5");
        hashedCredentialsMatcher.setHashIterations(128);
        return hashedCredentialsMatcher;
    }

    //配置 realm
    @Bean
    public ShiroRealm shiroRealm(HashedCredentialsMatcher hashedCredentialsMatcher){
        ShiroRealm shiroRealm = new ShiroRealm();
        shiroRealm.setCredentialsMatcher(hashedCredentialsMatcher);
        return shiroRealm;
    }
    //配置缓存
    @Bean
    public EhCacheManager ehCacheManager(){
        EhCacheManager ehCacheManager = new EhCacheManager();
        ehCacheManager.setCacheManagerConfigFile("classpath:ehcache.xml");
        return ehCacheManager ;
    }

    //配置安全管理器
    @Bean
    public DefaultWebSecurityManager defaultWebSecurityManager(ShiroRealm shiroRealm, EhCacheManager ehCacheManager){
        DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager();
        defaultWebSecurityManager.setRealm(shiroRealm);
        defaultWebSecurityManager.setCacheManager(ehCacheManager);
        return defaultWebSecurityManager;
    }

    @Bean //代理生成器，需要借助SpringAOP来扫描@RequiresRoles和@RequiresPermissions等注解，生成代理类实现功能增强，从而实现权限控制
    public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
        DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator =
                new DefaultAdvisorAutoProxyCreator();
        // 强制使用cglib，防止重复代理和可能引起代理出错的问题
        defaultAdvisorAutoProxyCreator.setProxyTargetClass(true);
        return defaultAdvisorAutoProxyCreator;
    }

    //配合DefaultAdvisorAutoProxyCreator  使用权限注解
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(DefaultWebSecurityManager defaultWebSecurityManager) {
        AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor();
        advisor.setSecurityManager(defaultWebSecurityManager);
        return advisor;
    }

    //過濾器
    @Bean
    public ShiroFilterFactoryBean shiroFilterFactoryBean(DefaultWebSecurityManager defaultWebSecurityManager){
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(defaultWebSecurityManager);

        shiroFilterFactoryBean.setLoginUrl("/login.html"); //设置进入登录页面的url
        shiroFilterFactoryBean.setUnauthorizedUrl("/unauthority.html");  //设置没有权限
        shiroFilterFactoryBean.setSuccessUrl("/main.html"); //设置登录成功url
        shiroFilterFactoryBean.setSuccessUrl("/order.html");

        Map<String,String> map = new LinkedHashMap<String, String>();

        // 设置权限
        map.put("/login.html","anon");
        map.put("/bootstrap/**","anon");
        map.put("/css/**","anon");
        map.put("/fonts/**","anon");
        map.put("/img/**","anon");
        map.put("/jquery/**","anon");
        map.put("/script/**","anon");
        map.put("/ztree/**","anon");
        map.put("/myjs/**","anon");

        map.put("/user/login","anon");
        map.put("/exit","logout");
        map.put("/tree.html","anon");

        map.put("/**","authc");

        shiroFilterFactoryBean.setFilterChainDefinitionMap(map);
        return shiroFilterFactoryBean;
    }

    //shiro的方言 在thymeleaf使用shiro標籤的
    @Bean
    public ShiroDialect shiroDialect(){
        return new ShiroDialect();
    }

}
